package com.invengo.module_check.ui.fragment.book_listing;

import android.annotation.SuppressLint;
import android.app.Application;
import android.text.TextUtils;

import com.invengo.base.utils.BeanMapperUtils;
import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.ShelfBean;
import com.invengo.library_rfid.classify.AnalyzeImpl;
import com.invengo.library_rfid.classify.RFIDCallBackListener;
import com.invengo.library_rfid.classify.RfidModelImpl;
import com.invengo.library_rfid.entity.TagInfo;
import com.invengo.module_check.BR;
import com.invengo.module_check.R;
import com.invengo.module_check.data.repsitory.business.BusinessRepsitory;
import com.invengo.module_check.ui.fragment.book_listing.item.BookListingItemViewModel;

import java.util.List;
import java.util.stream.Collectors;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableInt;
import androidx.databinding.ObservableList;

import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.base.ItemViewModel;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import me.tatarka.bindingcollectionadapter2.BindingRecyclerViewAdapter;
import me.tatarka.bindingcollectionadapter2.ItemBinding;

public class BookListingViewModel extends BaseViewModel<BusinessRepsitory> {
    public String currentShelfCode;
    public SingleLiveEvent<String> currentShelfName = new SingleLiveEvent<>();
    public ObservableInt inShelfBookCount = new ObservableInt(0);
    public ObservableInt newBookCount = new ObservableInt(0);

    public UIChangeObservable ui = new UIChangeObservable();
    public BindingRecyclerViewAdapter adapter = new BindingRecyclerViewAdapter();
    public ObservableList<BookListingItemViewModel> bookItemList = new ObservableArrayList<>();
    public ItemBinding<BookListingItemViewModel> bookitemBinding = ItemBinding.of(BR.viewModel, R.layout.item_book_listing);

    public RFIDCallBackListener rfidService =
            new RFIDCallBackListener(AnalyzeImpl.TO_BOOK,
                    tagInfo -> onScanResult(tagInfo),
                    state -> isReading.set(state));

    public BookListingViewModel(@NonNull Application application) {
        super(application, BusinessRepsitory.getInstance());
        registerRFID(rfidService);
    }

    public class UIChangeObservable {
        public SingleLiveEvent<List<BookBean>> listingBookEvent;

        public UIChangeObservable() {
            listingBookEvent = new SingleLiveEvent<>();
        }
    }

    //    @Override
    public void onScanResult(TagInfo tagInfo) {
        if (tagInfo.getRfidModel() == RfidModelImpl.TID) {
            getBookByTid(tagInfo.getTag());
        } else {
            getBookByCode(tagInfo.getTag());
        }
    }

    /**
     * 按Tid查询书本
     *
     * @param tid 标签
     */
    private void getBookByTid(String tid) {
        model.getBookByTid(tid)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bookBean -> addItem(bookBean));
    }

    /**
     * 按Tid查询书本
     *
     * @param code 标签
     */
    private void getBookByCode(String code) {
        model.getBookByCode(code)
                .compose(RxUtils.applySchedulersIO(getLifecycleProvider(), this))
                .subscribe(bookBean -> addItem(bookBean));
    }


    /**
     * 获取position的方式有很多种,indexOf是其中一种，常见的还有在Adapter中、ItemBinding.of回调里
     *
     * @return
     */
    public int getPosition(BookListingItemViewModel item) {
        return bookItemList.indexOf(item);
    }


    /**
     * 清除所有数据
     */
    public BindingCommand cleanAllData = new BindingCommand(() -> {
        cleanRFIDCacheNotStop();
        bookItemList.clear();
        newBookCount.set(0);
        inShelfBookCount.set(0);
    });

    /**
     * 添加项目
     *
     * @param bean 豆
     */
    private void addItem(BookBean bean) {
        if (TextUtils.isEmpty(bean.getShelfCode())) {
            newBookCount.set(newBookCount.get() + 1);
            bookItemList.add(new BookListingItemViewModel(this, bean));
        } else {
            inShelfBookCount.set(inShelfBookCount.get() + 1);
            bookItemList.add(new BookListingItemViewModel(this, bean));
        }
    }

    /**
     * 清除所有数据
     */
    public BindingCommand conformListing = new BindingCommand(() -> bookListing());

    /**
     * 图书上架
     */
    private void bookListing() {
        List<BookBean> collect;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            collect = bookItemList.stream()
                    .map(item -> item.book.getValue())
                    .filter(bean -> TextUtils.isEmpty(bean.getShelfCode()))
                    .collect(Collectors.toList());
        } else {
            collect = StreamSupport.stream(bookItemList)
                    .map(item -> item.book.getValue())
                    .filter(bean -> TextUtils.isEmpty(bean.getShelfCode()))
                    .collect(java8.util.stream.Collectors.toList());
        }
        if (collect.isEmpty()) {
            showErrorDialog("列表中无可上架图书");
            return;
        }
        model.bookListing(collect, currentShelfCode, currentShelfName.getValue())
                .compose(RxUtils.applySchedulersToast(getLifecycleProvider(), this))
                .subscribe(updateResult -> {
                    cleanAllData.execute();
                    ui.listingBookEvent.postValue(BeanMapperUtils.cloneList(collect));
                }, throwable -> {
                    cleanAllData.execute();
                    ui.listingBookEvent.postValue(null);
                });
    }

    public void onItemRemove(ItemViewModel item) {
        if (TextUtils.isEmpty(((BookListingItemViewModel) item).book.getValue().getShelfCode())) {
            newBookCount.set(newBookCount.get() - 1);
        } else {
            inShelfBookCount.set(inShelfBookCount.get() - 1);
        }
        int position = bookItemList.indexOf(item);
        bookItemList.remove(position);
        adapter.notifyDataSetChanged();
        ToastUtils.showShort("删除成功");
    }

    public void updateShelfBean(ShelfBean shelfBeans) {
        if (shelfBeans == null)
            return;
        currentShelfCode = shelfBeans.getShelfCode();
        currentShelfName.postValue(shelfBeans.getShelfName());
    }
}
